﻿using System;
using System.Linq;

using Buddy.BehaviorTree;
using Buddy.Common;
using Buddy.CommonBot;
using Buddy.Swtor;

using WingIt.Dynamics;

using Action = Buddy.BehaviorTree.Action;


namespace WingIt.Routines
{
    //05/09/2012 Neo93
    public static class SithJuggernaut
    {
        [Class(CharacterClass.Warrior, AdvancedClass.Juggernaut, SkillTreeId.JuggernautRage)]
        [Behavior(BehaviorType.Pull)]
        public static Composite JuggernautRagePull()
        {
            return JuggernautRageCombat();
        }

        [Class(CharacterClass.Warrior, AdvancedClass.Juggernaut, SkillTreeId.JuggernautRage)]
        [Behavior(BehaviorType.Combat)]
        public static Composite JuggernautRageCombat()
        {
            return new PrioritySelector(
                Movement.StopInRange(0.3f),
                Spell.WaitForCast(),
                // Todo: Handle FURY effects!!!!
                //***Generel***
                Spell.Cast("Force Charge", ret => BuddyTor.Me.CurrentTarget.Distance >= .3f), //+3 Rage/15s CD/30m Range - Pull
                Spell.Cast("Unleash", castWhen => BuddyTor.Me.IsStunned),//Insignia/2m CD
                Spell.Cast("Frenzy", castWhen => !BuddyTor.Me.HasBuff("Fury")),
                //#Only 1 of these 3 buffs can be active at a time#
                Spell.Cast("Bloodthirst", castWhen => BuddyTor.Me.HasBuff("Fury") && BuddyTor.Me.InCombat),//5m CD
                Spell.Cast("Predation", castWhen => BuddyTor.Me.HasBuff("Fury") && BuddyTor.Me.HealthPercent <= 50 || (BuddyTor.Me.CurrentTarget.Distance >= 30 && !AbilityManager.CanCast("Force Charge", BuddyTor.Me.CurrentTarget))),
                Spell.Cast("Berserk", castWhen => BuddyTor.Me.HasBuff("Fury") && BuddyTor.Me.InCombat),
                //#
                Spell.Cast("Obfuscate", castwhen => BuddyTor.Me.CurrentTarget.Toughness == CombatToughness.Player || BuddyTor.Me.CurrentTarget.Toughness == CombatToughness.Standard || BuddyTor.Me.CurrentTarget.Toughness == CombatToughness.Strong || BuddyTor.Me.CurrentTarget.Toughness == CombatToughness.Weak),

                //**Defensive**
                Spell.BuffSelf("Cloak of Pain", castWhen => BuddyTor.Me.InCombat && BuddyTor.Me.HealthPercent <= 90),//1m CD
                Spell.BuffSelf("Saber Ward", castWhen => BuddyTor.Me.InCombat && BuddyTor.Me.HealthPercent <= 50),//3m CD
                Spell.BuffSelf("Force Camouflage", castWhen => BuddyTor.Me.InCombat && BuddyTor.Me.HealthPercent <= 20),//45s CD
                Spell.BuffSelf("Undying Rage", castWhen => BuddyTor.Me.InCombat && BuddyTor.Me.HealthPercent <= 10),//1m15s CD

                //**Offensive**
                Spell.Cast("Throw", castWhen => BuddyTor.Me.CurrentTarget.HealthPercent <= 20 && BuddyTor.Me.ResourceStat >= 3),//-3 Rage
                Spell.Cast("Pommel Strike", castWhen => BuddyTor.Me.CurrentTarget.IsStunned && (BuddyTor.Me.CurrentTarget.Toughness  == CombatToughness.Standard || BuddyTor.Me.CurrentTarget.Toughness == CombatToughness.Weak)),//strong skill but only usable on stunned - normal or weak - enemys
                Spell.Cast("Battering Assault", castWhen => BuddyTor.Me.ResourceStat <= 6),//+6 Rage/12s CD
                Spell.Cast("Assault", castWhen => BuddyTor.Me.ResourceStat <= 2),//+2 Rage

                //**CC**
                Spell.Cast("Disruption", castWhen => BuddyTor.Me.CurrentTarget.IsCasting && BuddyTor.Me.CurrentTarget.CastTimeEnd - TimeSpan.FromSeconds(1) >= DateTime.Now),
                Spell.Cast("Force Choke", castWhen => ((BuddyTor.Me.CurrentTarget.IsCasting && !AbilityManager.CanCast("Disruption", BuddyTor.Me.CurrentTarget) || BuddyTor.Me.HealthPercent <= 60)) && !BuddyTor.Me.HasBuff("Saber Ward")),
                Spell.Cast("Intimidating Roar", onUnit =>
                {
                    var previousTarget = BuddyTor.Me.CurrentTarget;
                    return
                        Helpers.Targets.FirstOrDefault(
                            t =>
                            t != previousTarget && (t.Toughness == CombatToughness.Strong)) ??
                        Helpers.Targets.FirstOrDefault(t => t != previousTarget);
                }, castWhen => Helpers.Targets.Count() >= 3),

                Spell.Cast("Force Crush", castWhen => BuddyTor.Me.ResourceStat >= 3 && !BuddyTor.Me.HasBuff("Shockwave")),
                Spell.Cast("Smash", castWhen =>
                {
                    if (BuddyTor.Me.CurrentTarget.Distance <= 0.5f && BuddyTor.Me.ResourceStat >= 3)
                    {
                        if (AbilityManager.HasAbility("Obliterate"))
                        {
                            if (BuddyTor.Me.HasBuff("Dominate")) //over lvl 20
                            {
                                return true;
                            }
                            else
                                return false;
                        }
                        else if (AbilityManager.HasAbility("Force Crush"))
                        {
                            if (BuddyTor.Me.HasBuff("Shockwave")) //over lvl 40
                            {
                                return true;
                            }
                            else
                                return false; //under lvl 20
                        }
                        else
                            return true;
                    }
                    else
                        return false;
                }),
                Spell.Cast("Obliterate", castWhen => BuddyTor.Me.CurrentTarget.Distance < 1f && BuddyTor.Me.ResourceStat >= 3),
                Spell.Cast("Vicious Slash", castWhen => BuddyTor.Me.ResourceStat >= 3 || BuddyTor.Me.HasBuff("Berserk")),
                Spell.Cast("Force Scream", castWhen => BuddyTor.Me.HasBuff("Blood Frenzy") && BuddyTor.Me.ResourceStat >= 2),//-2Rage/9s CD

                Movement.MoveTo(ret => BuddyTor.Me.CurrentTarget.Position, 0.3f)
                );
        }

        [Class(CharacterClass.Warrior, AdvancedClass.Juggernaut, SkillTreeId.JuggernautRage)]
        [Behavior(BehaviorType.OutOfCombat)]
        public static Composite JuggernautRageOutOfCombat()
        {
            return new PrioritySelector(
                Spell.Cast("Shii-Cho Form", ret => !BuddyTor.Me.HasBuff("Shii-Cho Form"))
             );
        }
    }
}
